/*
 * DEB.c
 *
 * Created: 9/04/2012 1:51:01 PM
 *  Author: Richard
 */ 

#include <avr/io.h>
#include <string.h>

#include "DEB.h"

static struct  
{
	uint16 u11DebounceCounter :11;
	uint16 boState			  :1;
	uint16 boLast			  :1;
	uint16 boOverride		  :1;
	uint16 boOverrideValue	  :1;
	uint16 boOverrideStable	  :1;
} DEB__astDebounceData[ DEB_nenNumberOfInputs ];

static const struct  
{
	DIO_tenLogicLevel (*pfGetInput)(DIO_tenPinName);
	DIO_tenPinName enPinName;
	DIO_tenLogicLevel enActiveLevel;
	uint16 u16DebounceTime;
} DEB__astDebounceInfo[ DEB_nenNumberOfInputs ] =
{
	#if 0
/* DEB_nenV_OK		*/ { &DIO_enGetInputLevel, DIO_nenV_OK,      tHi,  10 },
/* DEB_nenSD_OK		*/ { &DIO_enGetInputLevel, DIO_nenSD_OK,     tHi,  10 },
/* DEB_nenRTC_INT	*/ { &DIO_enGetInputLevel, DIO_nenRTC_INT,   tHi,  10 },
/* DEB_nenVBI_OK	*/ { &DIO_enGetInputLevel, DIO_nenVBI_OK,    tHi,  10 },
/* DEB_nenVBO_OK	*/ { &DIO_enGetInputLevel, DIO_nenVBO_OK,    tHi,  10 },
/* DEB_nenVIN_ADC   */ { &ADC_enGetLogicValue, DIO_nenVIN_SENSE, tHi, 100 }
	#else
/* DEB_nenCurrent   */ { &ADC_enGetLogicValue, DIO_nenCurrent,   tHi,  10 },		
	#endif	
};

static void DEB__vDebounceOneInput( DEB_tenInput enInput );

static void DEB__vDebounceOneInput( DEB_tenInput enInput )
{
	DIO_tenLogicLevel enCurrentLevel;
	
	if( enInput < DEB_nenNumberOfInputs )
	{
		enCurrentLevel = DEB__astDebounceInfo[enInput].pfGetInput(DEB__astDebounceInfo[enInput].enPinName);
		enCurrentLevel = ( enCurrentLevel == DEB__astDebounceInfo[enInput].enActiveLevel) ? tHi : tLo;
		
		if( DEB__astDebounceData[enInput].u11DebounceCounter < DEB__astDebounceInfo[enInput].u16DebounceTime )
		{
			DEB__astDebounceData[enInput].u11DebounceCounter++;
		}
		
		if( enCurrentLevel != DEB__astDebounceData[enInput].boLast )
		{
			DEB__astDebounceData[enInput].u11DebounceCounter = 0;
		}
		
		if( DEB__astDebounceData[enInput].u11DebounceCounter >= DEB__astDebounceInfo[enInput].u16DebounceTime )
		{
			DEB__astDebounceData[enInput].boState = enCurrentLevel;		
		}
		
		DEB__astDebounceData[enInput].boLast = enCurrentLevel;
	}
}	

void DEB_vInit( void )
{
	memset(&DEB__astDebounceData, 0, sizeof(DEB__astDebounceData));
}

void DEB_vMain( void )
{
	DEB_tenInput enInput;
	
	for( enInput = (DEB_tenInput)0; enInput < DEB_nenNumberOfInputs; enInput++ )
	{
		DEB__vDebounceOneInput( enInput );
	}
}

DIO_tenLogicLevel DEB_enGetState( DEB_tenInput enInput )
{
	DIO_tenLogicLevel enReturnValue = tLo;
	
	if( enInput < DEB_nenNumberOfInputs )
	{
		enReturnValue = (DIO_tenLogicLevel)DEB__astDebounceData[enInput].boState;
	}
	
	return enReturnValue;
}
